﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using SCGILite.Helper;
using SCGILite.NetLib;

namespace SCGILite
{
    public class SCgiResponse : INetOutputStream
    {
        #region StatuesCode
        int _StatuesCode = 200;
        public int StatuesCode
        {
            get { return _StatuesCode; }
            set { _StatuesCode = value; }
        }
        #endregion

        #region private
        int fsm = 0;
        Action<INetOutputStream> _sendStream = null;
        Action _OnClose = null;
        #endregion

        #region ctor
        public SCgiResponse(Action<INetOutputStream> sendStream, Action OnClose)
        {
            _OnClose = OnClose;
            _sendStream = sendStream;
        }
        #endregion

        #region Stream
        void CloseSession()
        {
            Interlocked.Exchange(ref fsm, 3);
            ActionHelper.SafeExcute(Interlocked.Exchange(ref _OnClose, null));
        }

        public int Read(byte[] buf, int offset, int len)
        {
            return 0;
        }

        public void Close()
        {
            CloseSession();
        }
        #endregion

        #region Response
        public void Response(INetOutputStream stream)
        {
            if (stream == null)
                return;
            int a = Interlocked.CompareExchange(ref fsm, 2, 1);
            if (a == 0)
                throw new Exception("Header no send!!");
            if (a == 3)
                throw new Exception("Response close!!");
            _sendStream(stream);
        }
        #endregion

        #region SetResponseHeaders
        public void SetResponseHeaders(IDictionary<string, string> Headers)
        {
            int a = Interlocked.CompareExchange(ref fsm, 1, 0);
            if (a != 0)
                throw new Exception("Header Have send!!");

            StringBuilder build = new StringBuilder();
            Dictionary<string, string> ss = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
            foreach (KeyValuePair<string, string> kv in Headers)
            {
                ss[kv.Key.Trim()] = kv.Value.Trim();
            }
            string s;
            string k = "Status";
            MemoryStream ms = new MemoryStream();
            if (ss.TryGetValue(k, out s))
            {
                ss.Remove(k);
            }
            else
            {
                s = HttpStatusCodeDesc.ToStatusString(this.StatuesCode);
            }
            build.AppendLine("Status: " + s);
            foreach (KeyValuePair<string, string> kv in Headers)
            {
                string key = kv.Key.Trim();
                string v = "";
                if (ss.TryGetValue(key, out v))
                {
                    build.AppendLine(kv.Key + ": " + v);
                }
            }
            build.AppendLine();
            byte[] buf = Encoding.UTF8.GetBytes(build.ToString());
            ms.Write(buf, 0, buf.Length);
            ms.Position = 0;
            this._sendStream(new NetOutputStream(ms));
        }
        #endregion

        #region EndResponse
        public void EndResponse()
        {
            int a = Interlocked.Exchange(ref fsm, 3);
            if (a != 3)
                _sendStream(this);
        }
        #endregion
        #region isEndResponse
        public bool isEndResponse
        {
            get { return (fsm == 3); }
        }
        #endregion

        public bool CanSyncRead
        {
            get { return true; }
        }

        public void BeginRead(byte[] buffer, int offset, int count, Action<int> endRead)
        {
            throw new NotImplementedException();
        }
    }
}
